 package com.distance;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List;

import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.widget.RelativeLayout;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import com.claim.SubmitClaimClient;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;
import com.google.android.maps.Projection;
import com.kmlparser.KMLParser;
import com.overlays.CurrentLocation;
import com.overlays.EndMarker;
import com.overlays.LastKnownLocation;
import com.overlays.RouteLine;
import com.overlays.StartMarker;
import com.route.DetailedLocation;
import com.route.Route;
import com.settings.SettingsAdapter;

public class Distance extends MapActivity {
    // Variables
    private MapView mapView;
    private LocationManager locationManager;
    private Location lastLocation;
    private LocationListener locationListener = new MyLocationListener();;
    private MapController mapController;
    private GeoPoint point;
    private GeoPoint defaultPoint;
    private double lng;
    private double lat;
    private String claimString;
    private Drawable currentLocationMarker;
    private GeoPoint currentLocationGeoPoint;

    private Spinner spinner;
    private TextView textView;
    private Menu mMenu;
    private MenuItem mItem1;
    private MenuItem mItem2;
    private MenuItem mItem3;
    private MenuItem mItem4;
    private MenuItem mItem5;
    private MenuItem mItem6;
    private KMLParser kmlParser;

    private SubMenu sMenu;
    private MenuItem sItem1;
    private MenuItem sItem2;
    private MenuItem sItem3;
    private MenuItem sItem4;

    //private Claim claim = new Claim();
    private RouteLine routeLineOverlay;

    private Drawable startPointer;
    private Drawable endPointer;
    private Drawable currentPointer;
    private Drawable submitPointer;
    private Drawable startPointerIcon;
    private Drawable endPointerIcon;
    private Drawable currentPointerIcon;
    private Drawable submitPointerIcon;
    private Drawable redPointer;

    /*
     * Drawable for waypoints.
     * There are only 10 of them.
     * To change to a arraylist with dynamic words when free
     */
    private Drawable wayPoint1, wayPoint2, wayPoint3, wayPoint4, wayPoint5, wayPoint6, wayPoint7, wayPoint8, wayPoint9, wayPoint10;

    private Drawable whitePixel;

    private StartMarker startMarker;
    private EndMarker endMarker;
    private LastKnownLocation lastKnownLocation;
    private CurrentLocation currentLocationOverlay;

    private AddWaypoint addWayPointOverlay;

    private Thread submitClaimThread, timerThread;
    private SubmitClaimClient claim;
    private ProgressDialog pd;
    private Builder submitClaimAlertBuilder;
    private Dialog submitClaimDialog;

    private SubmitClaimHandler submitClaimHandler;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.main);
	initPersistance();
	//init all markers
	initCurrentLocationMarker();
	textView = (TextView) findViewById(R.id.TextView01);
	textView.bringToFront();
	// textView.setText("");
	mapView = (MapView) findViewById(R.id.map);
	RelativeLayout zoomLayout = (RelativeLayout)findViewById(R.id.MainRelativeLayout);
	zoomLayout.addView(mapView.getZoomControls());
	mapController = mapView.getController();

	//init bookmarks? i forgot why this code is here and it is probally useless
	Bookmarks.init();

	mapController.setZoom(13);
	// init locationmanager (another reddundent code chunk)
	locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
	lastLocation = locationManager.getLastKnownLocation("gps");
	
	//set default point to center on in map. it would be the last known location of the device. 
	//but if there is no previous location, added a default location
	try {
	    defaultPoint = new GeoPoint((int) (lastLocation.getLatitude() * 1E6), (int) (lastLocation.getLongitude() * 1E6));
	}catch(Exception e) {
	    defaultPoint = new GeoPoint(1319984, 104002203);
	}

	//draw the route and start and end markers if there is a start and end set
	if (((Route.start != null) && (Route.end != null))) {
	    routeLineOverlay = new RouteLine(getApplicationContext());
	    if(Route.fromClaim) {
		fromClaim();
	    }else {
		if(Route.wayPoints.size()>0) hasWaypoints();
	    	else hasNoWaypoints();
	    }
	    mapController.setCenter(Route.end.getGeoPoint());
	} else {
	    //if there is start point but no end point, we center the map over the start point.
	    //we try to put the start marker on the actual start of the road as the start point may not be on a road
	    if (Route.start != null) {
		mapController.setCenter(Route.start.getGeoPoint());
		if (Route.markers.size() > 0) {
		    mapView.getOverlays().add(
			    new StartMarker(startPointer, Route.markers.get(0),
				    getApplicationContext()));
		} else {
		    mapView.getOverlays().add(
			    new StartMarker(startPointer, Route.start
				    .getGeoPoint(), getApplicationContext()));
		}
	    }

	    if (Route.end != null) {
		//if there is end point we center map to end point
		mapController.setCenter(Route.end.getGeoPoint());
		endMarker = new EndMarker(endPointer, Route.end.getGeoPoint(),
			getApplicationContext());
		mapView.getOverlays().add(endMarker);
	    }
	    //draw lastknownlocation if nostart and end
	    if ((Route.end == null) && (Route.start == null)) {
		mapController.setCenter(defaultPoint);
		mapView.getOverlays().add(new LastKnownLocation(redPointer, defaultPoint,getApplicationContext()));
	    }
	}
    }

    //key events...mostly used for testing
    public boolean onKeyDown(int keyCode, KeyEvent event) {
	if (keyCode == KeyEvent.KEYCODE_I) {
	    // Zoom In
	    int level = mapView.getZoomLevel();
	    mapController.setZoom(level + 1);
	    return true;
	} else if (keyCode == KeyEvent.KEYCODE_O) {
	    // Zoom Out
	    int level = mapView.getZoomLevel();
	    mapController.setZoom(level - 1);
	    return true;
	} else if (keyCode == KeyEvent.KEYCODE_T) {
	    // Switch on traffic overlays
	    if (mapView.isSatellite()) {
		mapView.setSatellite(false);
	    } else
		mapView.setSatellite(true);
	    return true;
	} else if (keyCode == KeyEvent.KEYCODE_C) {
	    DHashMap.test = "This is the String of destiny.";
	    // locationManager =
	    // (LocationManager)getSystemService(Context.LOCATION_SERVICE);
	    // lastLocation = locationManager.getLastKnownLocation("gps");
	    // lastLocation =
	    // locationManager.getLastKnownLocation(LOCATION_SERVICE);
	    Criteria criteria = new Criteria();
	    criteria.setAccuracy(Criteria.ACCURACY_FINE);
	    criteria.setAltitudeRequired(false);
	    criteria.setBearingRequired(false);
	    criteria.setCostAllowed(true);
	    criteria.setPowerRequirement(Criteria.POWER_LOW);

	    String provider = locationManager.getBestProvider(criteria, true);
	    Location location = locationManager.getLastKnownLocation(provider);
	    mapController.setCenter(new GeoPoint(
		    (int) (location.getLatitude() * 1E6), (int) (location
			    .getLongitude() * 1E6)));
	    Toast
	    .makeText(Distance.this,
		    Double.toString(location.getLatitude()),
		    Toast.LENGTH_SHORT).show();
	    return true;
	} else if (keyCode == KeyEvent.KEYCODE_D) {
	    String[] test;
	    if (1 == 1) {
		// double endLat =
		// (Route.end.getGeoPoint().getLatitudeE6()/1E6);
		// double endLng =
		// (Route.end.getGeoPoint().getLongitudeE6()/1E6);
		test = new String[] {
			Double.toString(Route.start.getGeoPoint()
				.getLatitudeE6() / 1E6)
				+ ","
				+ Double.toString(Route.start.getGeoPoint()
					.getLongitudeE6() / 1E6),
					Double
					.toString(Route.end.getGeoPoint()
						.getLatitudeE6() / 1E6)
						+ ","
						+ Double.toString(Route.end.getGeoPoint()
							.getLongitudeE6() / 1E6) };
	    }
	    // test = {"1.3336884437452605,103.9581298828125",
	    // "1.3765917840991781,103.84929656982422"};
	    kmlParser = new KMLParser();

	    Toast.makeText(Distance.this, kmlParser.getDistance(test),
		    Toast.LENGTH_SHORT).show();
	    return true;
	} else if (keyCode == KeyEvent.KEYCODE_A) {
	    testSOAP();
	    //bookmarks.BookmarksAdapter.saveBookmarkList(Bookmarks.locationList);
	    // Switch on traffic overlays
	    //Drawable wayPointer = getResources().getDrawable(R.drawable.waypoint);
	    //wayPointer.setBounds(0, 0, wayPointer.getIntrinsicWidth(), wayPointer.getIntrinsicHeight());
	    //Route.markers = kmlParser.getRoutePoints();
	    //routeLineOverlay = new RouteLine(getApplicationContext());
	    //mapView.getOverlays().add(routeLineOverlay);
	    // mapView.getOverlays().add(new RouteOverlay(wayPointer,
	    // kmlParser.getRoutePoints()));
	    return true;
	} else if (keyCode == KeyEvent.KEYCODE_P){
	    addWayPointOverlay= new AddWaypoint(whitePixel, null,getApplicationContext());
	    mapView.getOverlays().add(addWayPointOverlay);
	    return true;
	}else if (keyCode == KeyEvent.KEYCODE_L){
	    submitClaimHandler = new SubmitClaimHandler();
	    submitClaimHandler.sendEmptyMessage(0);
	    return true;
	}else if (keyCode == KeyEvent.KEYCODE_Q){
	    submitClaimDialog = new AlertDialog.Builder(Distance.this)
	    .setTitle("Claim Status")
	    .setMessage("Unable to connect to server.\nPlease try again.")
	    .setPositiveButton("OK",null)
	    .create();
	    submitClaimDialog.show();
	    return true;
	}else if (keyCode == KeyEvent.KEYCODE_W){
	    this.startActivity(new Intent(Intent.ACTION_VIEW,Uri.parse(
		    "http://maps.google.com/maps?f=d&saddr="
		    + Double.toString(Route.start.getGeoPoint().getLatitudeE6() / 1E6)
		    + ","
		    + Double.toString(Route.start.getGeoPoint().getLongitudeE6() / 1E6) 
		    + "&daddr="
		    + Double.toString(Route.end.getGeoPoint().getLatitudeE6() / 1E6)
		    + ","
		    + Double.toString(Route.end.getGeoPoint().getLongitudeE6() / 1E6)
		    + "&hl=en"
	    ))
	    );
	    return true;
	}
	else
	    return false;
    }

    //creating the menu and sub menu
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
	mMenu = menu;

	// Add the menu
	mItem1 = mMenu.add("Set Start");
	mItem1.setIcon(startPointer);
	mItem2 = mMenu.add("Set End");
	mItem2.setIcon(endPointer);
	mItem3 = mMenu.add("Set Waypoints");
	mItem4 = mMenu.add("Get Location");
	mItem4.setIcon(currentPointerIcon);
	mItem5 = mMenu.add("Submit Claim");
	mItem5.setIcon(submitPointer);

	// Add the submenu.
	sMenu = mMenu.addSubMenu("More");
	sItem1 = sMenu.add("Driving Directions");
	sItem2 = sMenu.add("Edit Bookmarks");
	sItem3 = sMenu.add("Settings");
	sItem4 = sMenu.add("Claims History");
	sMenu.add("Cancel");

	return true;
    }

    //event handler for the menu and sub menu
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
	if (item.equals(mItem1)) {
	    Intent intent = new Intent();
	    intent.setClassName("com.distance", "com.distance.Start");
	    startActivity(intent);
	    return true;
	} else if (item.equals(mItem2)) {
	    Intent intent = new Intent();
	    intent.setClassName("com.distance", "com.distance.Destination");
	    startActivity(intent);
	    // intent.setAction(action)
	    return true;
	} else if (item.equals(mItem3)){
	    if (mItem3.getTitle().equals("Set Waypoints")){
		if (((Route.start != null) && (Route.end != null))){
		    addWayPointOverlay= new AddWaypoint(whitePixel, null,getApplicationContext());
		    mapView.getOverlays().add(addWayPointOverlay);
		    mItem3.setTitle("Clear Waypoints");
		}else{
		    new AlertDialog.Builder(Distance.this)
		    .setTitle("Error")
		    .setMessage("Please set your start point and end point before adding a waypoint.")
		    .setPositiveButton("OK",null)
		    .create()
		    .show();
		}
	    }else{
		mapView.getOverlays().remove(addWayPointOverlay);
		mapView.getOverlays().clear();
		mapView.invalidate();
		clearWayPoints();
		hasNoWaypoints();
		mItem3.setTitle("Set Waypoints");
	    }

	    return true;
	}else if (item.equals(mItem4)) {
	    if (mItem4.getTitle().equals("Get Location")) {
		locationManager.requestLocationUpdates(
			LocationManager.GPS_PROVIDER, 0, 0, locationListener);
		mItem4.setTitle("Stop Location");
	    } else {
		locationManager.removeUpdates(locationListener);
		mItem4.setTitle("Get Location");
	    }
	} else if (item.equals(mItem5)) {
	    pd = ProgressDialog.show(Distance.this, "Please Wait", "Submitting Claim", true, false);
	    claim = new SubmitClaimClient();
	    claimString = null;

	    submitClaimDialog  = new AlertDialog.Builder(Distance.this)
	    .setTitle("Claim Status")
	    .setMessage("Unable to connect to server.\nPlease try again.")
	    .setPositiveButton("OK",null)
	    .create();
	    submitClaimHandler = new SubmitClaimHandler();

	    submitClaimThread = new Thread() {
		public void run(){
		    //String addressInput = adress.getText().toString(); // Get input text
		    try {
			claimString = claim.submitClaim();
			//pd.dismiss();
			//submitClaimHandler.sendMessage(null);
		    } catch (Exception e) {
		    }
		}
	    };

	    timerThread = new Thread() {
		public void run(){
		    try {
			Thread.sleep(5000);
			submitClaimHandler.sendEmptyMessage(0);
			submitClaimThread = null;
		    } catch (Exception e) {
		    }
		}
	    };

	    submitClaimThread.start();
	    timerThread.start();
	    return true;
	} else if (item.equals(sItem1)) {
	    if (((Route.start != null) && (Route.end != null))){
		this.startActivity(new Intent(Intent.ACTION_VIEW,Uri.parse(
			"http://maps.google.com/maps?f=d&saddr="
			+ Double.toString(Route.start.getGeoPoint().getLatitudeE6() / 1E6)
			+ ","
			+ Double.toString(Route.start.getGeoPoint().getLongitudeE6() / 1E6) 
			+ "&daddr="
			+ Double.toString(Route.end.getGeoPoint().getLatitudeE6() / 1E6)
			+ ","
			+ Double.toString(Route.end.getGeoPoint().getLongitudeE6() / 1E6)
			+ "&hl=en"
		))
		);
	    }else{
	    	new AlertDialog.Builder(Distance.this)
		    .setTitle("Driving Directions")
		    .setMessage("You need a start and end point to get driving directions.")
		    .setPositiveButton("OK",null)
		    .create();
	    }
	    return true;
	} else if (item.equals(sItem2)) {
	    Intent intent = new Intent();
	    intent.setClassName("com.distance", "com.distance.BookmarksList");
	    startActivity(intent);
	    return true;
	} else if (item.equals(sItem3)) {
	    Intent intent = new Intent();
	    intent.setClassName("com.distance", "com.distance.Settings");
	    startActivity(intent);
	    return true;
	} else if (item.equals(sItem4)) {
	    Intent intent = new Intent();
	    intent.setClassName("com.distance", "com.distance.ClaimsHistoryList");
	    startActivity(intent);
	    return true;
	} 
	return false;

    }

    // Display Map (useless and redundent method as google does *not* allow displaying of route)
    @Override
    protected boolean isRouteDisplayed() {
	return true;
    }

    //location listener to receive location change updates
    public class MyLocationListener implements LocationListener {

	public void onLocationChanged(Location arg0) {

	    mapView.getOverlays().remove(currentLocationOverlay);
	    mapView.invalidate();
	    Route.currentLocation = new GeoPoint(
		    (int) (arg0.getLatitude() * 1E6), (int) (arg0
			    .getLongitude() * 1E6));
	    currentLocationOverlay = new CurrentLocation(currentPointer, Route.currentLocation,getApplicationContext());
	    mapView.getOverlays().add(currentLocationOverlay);
	    mapController.animateTo(Route.currentLocation);
	    Toast.makeText(
		    Distance.this,
		    Double.toString(arg0.getLatitude()) + ","
		    + Double.toString(arg0.getLongitude()),
		    Toast.LENGTH_SHORT).show();

	}

	public void onProviderDisabled(String arg0) {
	    // TODO Auto-generated method stub

	}

	public void onProviderEnabled(String arg0) {
	    // TODO Auto-generated method stub

	}

	public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
	    // TODO Auto-generated method stub

	}

    }

    public class MyLocationOverlay extends ItemizedOverlay<OverlayItem> {

	private List<OverlayItem> mItemList = new ArrayList<OverlayItem>();
	private Drawable defaultMarker;

	public MyLocationOverlay(Drawable defaultMarker, GeoPoint p) {
	    super(defaultMarker);
	    this.defaultMarker = defaultMarker;
	    mItemList.add(new OverlayItem(p, "Title", "Snippet"));

	    populate();

	    // TODO Auto-generated constructor stub
	}

	@Override
	protected OverlayItem createItem(int i) {
	    // TODO Auto-generated method stub
	    return mItemList.get(i);

	}

	@Override
	protected boolean onTap(int i) {
	    // final MockContext context = new MockContext();
	    Toast.makeText(Distance.this, "Your Last Known Location",
		    Toast.LENGTH_SHORT).show();

	    return true;

	}

	@Override
	public int size() {
	    return mItemList.size();
	}

	@Override
	public void draw(Canvas canvas, MapView mapView, boolean shadow) {
	    super.draw(canvas, mapView, shadow);
	    boundCenterBottom(defaultMarker);
	}

    }

    //overlay to draw route...not used
    public class RouteOverlay extends ItemizedOverlay<OverlayItem> {

	private List<OverlayItem> mItemList = new ArrayList<OverlayItem>();

	public RouteOverlay(Drawable defaultMarker, GeoPoint[] p) {
	    super(defaultMarker);
	    Projection projection = mapView.getProjection();
	    Canvas canvas = new Canvas();
	    canvas.drawColor(Color.BLUE);
	    Point preTempPoint = new Point();
	    GeoPoint tempGP = null;
	    Paint paint = new Paint();
	    paint.setStrokeWidth(16);
	    paint.setColor(Color.BLUE);
	    canvas.drawLine(20, 20, 140, 370, paint);
	    for (GeoPoint gp : p) {
		mItemList.add(new OverlayItem(gp, "Title", "Snippet"));

		if (tempGP != null) {
		    Point curTempPoint = new Point();
		    projection.toPixels(gp, curTempPoint);
		    canvas.drawLine(preTempPoint.x, preTempPoint.y,
			    curTempPoint.x, curTempPoint.y, paint);
		    tempGP = gp;
		    preTempPoint = curTempPoint;
		} else {
		    tempGP = gp;
		    preTempPoint = projection.toPixels(gp, preTempPoint);
		}

	    }

	    // canvas.drawLine(startX, startY, stopX, stopY, paint)

	    populate();

	    // TODO Auto-generated constructor stub
	}

	@Override
	protected OverlayItem createItem(int i) {
	    // TODO Auto-generated method stub
	    return mItemList.get(i);

	}

	@Override
	protected boolean onTap(int i) {
	    // final MockContext context = new MockContext();
	    Toast.makeText(Distance.this, "This is where you are now",
		    Toast.LENGTH_SHORT).show();

	    return true;

	}

	@Override
	public int size() {
	    // TODO Auto-generated method stub
	    return mItemList.size();
	}

    }

    /*
     * private class currentLocation extends ItemizedOverlay<OverlayItem> {
     * LastKnownLocation data = new LastKnownLocation(new
     * ArrayList<OverlayItem>());
     * 
     * public currentLocation(Drawable pMarker) { super(pMarker);
     * this.data.pMarker = pMarker; data.mItemList.add(new
     * OverlayItem(Route.currentLocation, "Title", "Snippet")); populate(); }
     * 
     * @Override protected OverlayItem createItem(int pIndex) { return
     * data.mItemList.get(pIndex); }
     * 
     * @Override public int size() { return data.mItemList.size(); }
     * 
     * @Override public void draw(Canvas canvas, MapView mapView, boolean
     * shadow) { super.draw(canvas, mapView, shadow);
     * boundCenterBottom(data.pMarker); }
     * 
     * }
     */

    // test method...use with caution and remember its just for testing
    public void test(){
	try{
	    FileOutputStream fOut = openFileOutput("samplefile.txt", MODE_WORLD_READABLE);
	    OutputStreamWriter osw = new OutputStreamWriter(fOut); 

	    // Write the string to the file
	    osw.write("this is a test of the android application io function");
	    /* ensure that everything is
	     * really written out and close */
	    osw.flush();
	    osw.close();

	    FileInputStream fIn = openFileInput("samplefile.txt");
	    InputStreamReader isr = new InputStreamReader(fIn);
	    BufferedReader br = new BufferedReader(isr);
	    String strLine;
	    while ((strLine = br.readLine()) != null){
		Toast.makeText(Distance.this,strLine,Toast.LENGTH_SHORT).show();
	    }
	    /* Prepare a char-Array that will
	     * hold the chars we read back in. */
	    //char[] inputBuffer = new char[TESTSTRING.length()];
	    // Fill the Buffer with data from the file
	    //isr.read(inputBuffer);
	    // Transform the chars to a String
	    //String readString = new String(isr.toString()); 

	}catch(Exception e){

	}
	try{
	    FileInputStream fIn = openFileInput("bookmarks.txt");
	    InputStreamReader isr = new InputStreamReader(fIn);
	    BufferedReader br = new BufferedReader(isr);
	}catch(FileNotFoundException e){

	}
    }

    //test SOAP web service
    public void testSOAP(){
	SoapObject request = new SoapObject("http://calculator.me.org/", "add");
	request.addProperty("i", 5);
	request.addProperty("j", 5);
	SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
	envelope.setOutputSoapObject(request);
	HttpTransportSE androidHttpTransport = new HttpTransportSE("http://172.20.130.229:8080/CalculatorWSApplication/CalculatorWSService?WSDL"); 
	try
	{
	    //Object resultRequestSOAP = null; 
	    androidHttpTransport.call("add", envelope);
	    String resultsRequestSOAP = envelope.getResponse().toString();
	    String results = (String) resultsRequestSOAP;
	    Toast.makeText(Distance.this," " + results,Toast.LENGTH_SHORT).show();
	}
	catch (Exception aE)
	{
	    //aE.
	    Toast.makeText(Distance.this, aE.toString()+aE.getMessage(),Toast.LENGTH_SHORT).show();
	} 
    }

    //code to add way points
    public void addWayPointLogic(GeoPoint wayPointGeoPoint){
	//Route.wayPoints.add(new DetailedLocation("empty",wayPointGeoPoint,"Enter a detailed description"));
	mapView.getOverlays().add(new CurrentLocation(currentPointer, wayPointGeoPoint, getApplicationContext()));
	Route.wayPoints.add(new DetailedLocation("",wayPointGeoPoint,""));
	//since code has waypoints, we call the logic to redraw route
	hasWaypoints();
    }

    //code to init drawable markers
    public void initCurrentLocationMarker() {
	whitePixel = getResources().getDrawable(R.drawable.whitepixel);
	whitePixel.setBounds(0, 0, whitePixel.getIntrinsicWidth(), whitePixel.getIntrinsicHeight());

	currentLocationMarker = getResources().getDrawable(
		R.drawable.red_pointer);
	currentLocationMarker.setBounds(0, 0, currentLocationMarker
		.getIntrinsicWidth(), currentLocationMarker
		.getIntrinsicHeight());

	currentPointer = getResources().getDrawable(R.drawable.currentlocation);
	currentPointer.setBounds(0, 0, currentPointer.getIntrinsicWidth(),
		currentPointer.getIntrinsicHeight());

	currentPointerIcon = getResources().getDrawable(
		R.drawable.currentlocation);
	currentPointerIcon.setBounds(0, 0, currentPointerIcon
		.getIntrinsicWidth(), currentPointerIcon.getIntrinsicHeight());

	submitPointer = getResources().getDrawable(R.drawable.submit);
	submitPointer.setBounds(0, 0, submitPointer.getIntrinsicWidth(),
		submitPointer.getIntrinsicHeight());

	redPointer = getResources().getDrawable(R.drawable.red_pointer);
	redPointer.setBounds(0, 0, redPointer.getIntrinsicWidth(), redPointer
		.getIntrinsicHeight());

	startPointer = getResources().getDrawable(R.drawable.start);
	startPointer.setBounds(0, 0, startPointer.getIntrinsicWidth(),
		startPointer.getIntrinsicHeight());

	endPointer = getResources().getDrawable(R.drawable.end);
	endPointer.setBounds(0, 0, endPointer.getIntrinsicWidth(), endPointer
		.getIntrinsicHeight());

	wayPoint1 = getResources().getDrawable(R.drawable.end);
	wayPoint1.setBounds(0, 0, wayPoint1.getIntrinsicWidth(), endPointer
		.getIntrinsicHeight());

	wayPoint2 = getResources().getDrawable(R.drawable.end);
	wayPoint2.setBounds(0, 0, wayPoint2.getIntrinsicWidth(), endPointer
		.getIntrinsicHeight());

	wayPoint3 = getResources().getDrawable(R.drawable.end);
	wayPoint3.setBounds(0, 0, wayPoint3.getIntrinsicWidth(), endPointer
		.getIntrinsicHeight());

	wayPoint4 = getResources().getDrawable(R.drawable.end);
	wayPoint4.setBounds(0, 0, wayPoint4.getIntrinsicWidth(), endPointer
		.getIntrinsicHeight());

	wayPoint5 = getResources().getDrawable(R.drawable.end);
	wayPoint5.setBounds(0, 0, wayPoint5.getIntrinsicWidth(), endPointer
		.getIntrinsicHeight());

	wayPoint6 = getResources().getDrawable(R.drawable.end);
	wayPoint6.setBounds(0, 0, wayPoint6.getIntrinsicWidth(), endPointer
		.getIntrinsicHeight());

	wayPoint7 = getResources().getDrawable(R.drawable.end);
	wayPoint7.setBounds(0, 0, wayPoint7.getIntrinsicWidth(), endPointer
		.getIntrinsicHeight());

	wayPoint8 = getResources().getDrawable(R.drawable.end);
	wayPoint8.setBounds(0, 0, wayPoint8.getIntrinsicWidth(), endPointer
		.getIntrinsicHeight());

	wayPoint9 = getResources().getDrawable(R.drawable.end);
	wayPoint9.setBounds(0, 0, wayPoint9.getIntrinsicWidth(), endPointer
		.getIntrinsicHeight());

	wayPoint10 = getResources().getDrawable(R.drawable.end);
	wayPoint10.setBounds(0, 0, wayPoint10.getIntrinsicWidth(), endPointer
		.getIntrinsicHeight());

    }

    /*
     * Overlay class that has to be activated in order to add waypoints.
     * It gets the geopoint of a position clicked on the device and sends it to the addwaypointlogic method.
     */
    public class AddWaypoint extends Overlay{

	BitmapDrawable bmp;
	int w, h;
	Point p;
	private Context context;

	public AddWaypoint(Drawable d, Point p, Context _context) { 
	    context = _context;
	    bmp = (BitmapDrawable) d; 
	    this.p = p; 
	    w = bmp.getIntrinsicWidth(); 
	    h = bmp.getIntrinsicHeight(); 
	} 

	@Override
	public void draw(Canvas canvas, MapView mapView, boolean shadow) {
	    bmp.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
	    bmp.setAlpha(0);
	    bmp.draw(canvas);
	}

	@Override
	public boolean onTap(GeoPoint p, MapView mapView) {
	    Toast.makeText(context, p.toString(), Toast.LENGTH_SHORT).show();
	    addWayPointLogic(p);
	    return true;
	}

    }

    //code to execute if route contains waypoints
    private void hasWaypoints(){
	kmlParser = new KMLParser();
	DetailedLocation prevDL = null;
	int waypointCounter = 0;
	Route.routeLength = 0.0;
	String routeText = kmlParser.getDistance(Route.start.getGeoPoint().getLatitudeE6(),Route.start.getGeoPoint().getLongitudeE6(),Route.end.getGeoPoint().getLatitudeE6(),Route.end.getGeoPoint().getLongitudeE6());
	textView.setTextColor(Color.WHITE);
	textView.setBackgroundColor(Color.argb(255, 0, 0, 0));
	for(DetailedLocation tempDL : Route.wayPoints){
	    if(waypointCounter == 0){
		kmlParser.getDistance(Route.start.getGeoPoint().getLatitudeE6(),Route.start.getGeoPoint().getLongitudeE6(),tempDL.getGeoPoint().getLatitudeE6(),tempDL.getGeoPoint().getLongitudeE6());
		Route.markers = kmlParser.getRoutePoints();
		Route.routeLength += getDistanceInMeters(kmlParser.getRawDistance());
	    }else{
		kmlParser.getDistance(prevDL.getGeoPoint().getLatitudeE6(),prevDL.getGeoPoint().getLongitudeE6(),tempDL.getGeoPoint().getLatitudeE6(),tempDL.getGeoPoint().getLongitudeE6());
		Route.markers.addAll(kmlParser.getRoutePoints());
		Route.routeLength += getDistanceInMeters(kmlParser.getRawDistance());
	    }
	    if(waypointCounter == Route.wayPoints.size()-1){
		kmlParser.getDistance(tempDL.getGeoPoint().getLatitudeE6(),tempDL.getGeoPoint().getLongitudeE6(),Route.end.getGeoPoint().getLatitudeE6(),Route.end.getGeoPoint().getLongitudeE6());
		Route.markers.addAll(kmlParser.getRoutePoints());
		Route.routeLength += getDistanceInMeters(kmlParser.getRawDistance());
	    }
	    prevDL = tempDL;
	    waypointCounter++;
	}
	textView.setText(routeText + "\n" + Route.routeLength.toString() + " meters");
	mapView.getOverlays().add(routeLineOverlay);
    }

    private void hasNoWaypoints(){
	/*String[] startEnd;
	    startEnd = new String[] {
		    Double
		    .toString(Route.start.getGeoPoint().getLatitudeE6() / 1E6)
		    + ","
		    + Double.toString(Route.start.getGeoPoint()
			    .getLongitudeE6() / 1E6),
			    Double
			    .toString(Route.end.getGeoPoint().getLatitudeE6() / 1E6)
			    + ","
			    + Double.toString(Route.end.getGeoPoint()
				    .getLongitudeE6() / 1E6) };*/
	// test = {"1.3336884437452605,103.9581298828125",
	// "1.3765917840991781,103.84929656982422"};
	kmlParser = new KMLParser();

	// Toast.makeText(Distance.this,
	// kmlParser.getDistance(test),Toast.LENGTH_SHORT).show();
	String routeText = kmlParser.getDistance(Route.start.getGeoPoint().getLatitudeE6(),Route.start.getGeoPoint().getLongitudeE6(),Route.end.getGeoPoint().getLatitudeE6(),Route.end.getGeoPoint().getLongitudeE6());
	textView.setText(routeText + "\n" + getDistanceInMeters(kmlParser.getRawDistance()).toString() + " meters");
	textView.setTextColor(Color.WHITE);
	textView.setBackgroundColor(Color.argb(255, 0, 0, 0));
	// textView.on
	Drawable wayPointer = getResources().getDrawable(
		R.drawable.waypoint);
	wayPointer.setBounds(0, 0, wayPointer.getIntrinsicWidth(),
		wayPointer.getIntrinsicHeight());
	Route.routeLength = 0.0;
	Route.routeLength += getDistanceInMeters(kmlParser.getRawDistance());
	Route.markers = kmlParser.getRoutePoints();
	Route.routeLength += getDistanceInMeters(kmlParser.getRawDistance());
	mapView.getOverlays().add(routeLineOverlay);
	mapView.getOverlays().add(
		new StartMarker(startPointer, Route.markers.get(0),
			getApplicationContext()));
	mapView.getOverlays().add(
		new EndMarker(endPointer, Route.markers.get(Route.markers
			.size() - 1), getApplicationContext()));
    }
    
    private void fromClaim() {
	String routeText = "Start Location: " 
	    + Route.start.getLocationName() 
	    + " " 
	    + Route.start.getGeoPoint().toString() 
	    + "\nEnd Location: " 
	    + Route.end.getLocationName() 
	    + " " 
	    + Route.end.getGeoPoint().toString() 
	    + "\nDistance: " 
	    + Route.routeLength.toString()
	    + " meters";
	textView.setText(routeText);
	textView.setTextColor(Color.WHITE);
	textView.setBackgroundColor(Color.argb(75, 0, 0, 0));
	mapView.getOverlays().add(routeLineOverlay);
	mapView.getOverlays().add(
		new StartMarker(startPointer, Route.markers.get(0),
			getApplicationContext()));
	mapView.getOverlays().add(
		new EndMarker(endPointer, Route.markers.get(Route.markers
			.size() - 1), getApplicationContext()));
	Route.fromClaim = false;
	
    }

    private void clearWayPoints(){
	Route.wayPoints.clear();
    }

    private void removeWayPoint(){

    }

    private void showSubmitClaimResult(){
	if(true){
	    new AlertDialog.Builder(Distance.this)
	    .setTitle("Claim Status")
	    .setMessage("Unable to connect to server.\nPlease try again.")
	    .setPositiveButton("OK",null)
	    .create()
	    .show();
	}else{
	    new AlertDialog.Builder(Distance.this)
	    .setTitle("Claim Status")
	    .setMessage(claimString)
	    .setPositiveButton("OK",null)
	    .create()
	    .show();
	}

    }

    private class SubmitClaimHandler extends Handler{

	@Override
	public void handleMessage(Message msg) {
	    pd.dismiss();
	    if(claimString==null){
		new AlertDialog.Builder(Distance.this)
		.setTitle("Claim Status")
		.setMessage("Unable to connect to server.\nPlease try again.")
		.setPositiveButton("OK",null)
		.create()
		.show();
	    }else{
		new AlertDialog.Builder(Distance.this)
		.setTitle("Claim Status")
		.setMessage(claimString)
		.setPositiveButton("OK",null)
		.create()
		.show();
	    }
	    super.handleMessage(msg);
	}

    }

    public Double getDistanceInMeters(String rawDistance){
	if (rawDistance.endsWith("km")){
	    return 1000 * Double.parseDouble(rawDistance.substring(0, rawDistance.length()-2));
	}
	if (rawDistance.endsWith("mi")){
	    return 1609 * Double.parseDouble(rawDistance.substring(0, rawDistance.length()-2));
	}
	return 0.0;
    }

    public void initPersistance() {
	try {
	    //set context of bookmarks class
	    com.bookmarks.BookmarksProvider.context = getApplicationContext();
	    //read and parse in bookmark file
	    com.bookmarks.BookmarksProvider.readFile();
	    //convert raw data to detailed location objects
	    Bookmarks.getBookmarks();

	    com.settings.SettingsProvider.context = getApplicationContext();
	    com.settings.SettingsProvider.readFile();
	    SettingsAdapter.retriveSettings();
	}
	catch(Exception e) {

	}
    }
}